package com.tao.mvplibrary.utils;


import android.os.Handler;
import android.os.Looper;

import androidx.lifecycle.Lifecycle;

import com.uber.autodispose.AutoDispose;
import com.uber.autodispose.AutoDisposeConverter;
import com.uber.autodispose.android.lifecycle.AndroidLifecycleScopeProvider;

import org.reactivestreams.Subscriber;

import io.reactivex.Flowable;
import io.reactivex.FlowableTransformer;
import io.reactivex.android.schedulers.AndroidSchedulers;
import io.reactivex.schedulers.Schedulers;

public class RxFlowableUtils2 {


    /**
     * 订阅
     *
     * @param  observable    被观察者
     * @param observer      观察者
     * @param lifecycle     使用生命周期自动接绑  可为null
     * @param observeOnMain
     * @param <T>
     */
    public static <T> void toSubscribe( Flowable<T> observable, Subscriber<? super T> observer, Lifecycle lifecycle, boolean subscribeOnMain, boolean observeOnMain) {
        if (lifecycle == null) {
//            getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//            if (!subscribeOnMain) {
//                pool.execute(new Runnable() {
//                    @Override
//                    public void run() {
//                        getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//                    }
//                });
//            } else {
//                getEntityObservable(observable, subscribeOnMain, observeOnMain).subscribe(observer);
//            }
            toSub(observable, subscribeOnMain, observeOnMain, null, observer);
        } else {
            if (isThreadMain()) {
                toSub(observable, subscribeOnMain, observeOnMain, lifecycle, observer);
            } else {
                runOnui(new Runnable() {
                    @Override
                    public void run() {
                        toSub(observable, subscribeOnMain, observeOnMain, lifecycle, observer);
                    }
                });
            }

//            ((ObservableSubscribeProxy) observable.compose(getComposer(subscribeOnMain, observeOnMain)).as(bindLifecycle(lifecycle))).subscribe(observer);
        }
    }

    private static <T> void toSub( Flowable<T> observable, boolean subscribeOnMain, boolean observeOnMain, Lifecycle lifecycle, Subscriber<? super T> observer) {
         Flowable<T> tObservable = observable.subscribeOn(subscribeOnMain ? AndroidSchedulers.mainThread() : Schedulers.newThread())
                .observeOn(observeOnMain ? AndroidSchedulers.mainThread() : Schedulers.newThread());

        if (lifecycle != null) {
            tObservable.as(bindLifecycle(lifecycle)).subscribe(observer);

        } else {
            tObservable.subscribe(observer);
       
        }
    }

    public static void runOnui(Runnable runnable) {
        new Handler(Looper.getMainLooper()).post(runnable);
    }

    /**
     * 绑定 生命周期 默认观察者为main线程
     *
     * @param observable
     * @param resultObserver
     * @param lifecycle
     * @param <T>
     */
    public static <T> void toSubscribe( Flowable<T> observable, Subscriber<T> resultObserver, Lifecycle lifecycle) {
        toSubscribe(observable, resultObserver, lifecycle, false, true);
    }

    public static <T> void toSubscribe( Flowable<T> observable, Subscriber<T> resultObserver, Lifecycle lifecycle, boolean observeOnMain) {
        toSubscribe(observable, resultObserver, lifecycle, false, observeOnMain);
    }

    /**
     * 不绑定 生命周期 默认观察者为main线程
     *
     * @param observable
     * @param resultObserver
     * @param <T>
     */
    public static <T> void toSubscribe( Flowable<T> observable, Subscriber<T> resultObserver) {
        toSubscribe(observable, resultObserver, false, true);
    }


    /**
     * 不绑定 生命周期  自由设置观察者线程
     *
     * @param observable
     * @param resultObserver
     * @param <T>
     */
    public static <T> void toSubscribe( Flowable<T> observable, Subscriber<T> resultObserver, boolean obserMain) {
        toSubscribe(observable, resultObserver, false, obserMain);
    }

    public static <T> void toSubscribe( Flowable<T> observable, Subscriber<T> resultObserver, boolean subscribeOnMain, boolean obserMain) {
        toSubscribe(observable, resultObserver, null, subscribeOnMain, obserMain);
    }


    /**
     * 绑定到lifecycle
     *
     * @param lifecycle
     * @param <T>
     * @return
     */
    public static <T> AutoDisposeConverter<T> bindLifecycle(Lifecycle lifecycle) {
        return AutoDispose.autoDisposable(AndroidLifecycleScopeProvider.from(lifecycle, Lifecycle.Event.ON_DESTROY));
    }

    /**
     * 线程调度器
     *
     * @param <T>
     * @param subscribeOnMain
     * @param observeOnMain
     * @return
     */
    public static <T> FlowableTransformer<T, T> getComposer(final boolean subscribeOnMain, final boolean observeOnMain) {
        return new  FlowableTransformer<T, T>() {
            public  Flowable<T> apply( Flowable<T> upstream) {
                if (subscribeOnMain) {
                    upstream.subscribeOn(AndroidSchedulers.mainThread());
                } else {
                    if (isThreadMain()) {
                        upstream.subscribeOn(Schedulers.newThread());
                    }
                }
                if (observeOnMain) {
                    return upstream.observeOn(AndroidSchedulers.mainThread());
                } else {
                    return upstream.observeOn(Schedulers.io());
                }
            }
        };
    }

    private static boolean isThreadMain() {
        return Thread.currentThread().getName().equals(Looper.getMainLooper().getThread().getName());
    }

    /**
     * 是否切换到UI线程
     *
     * @param <T>
     * @param observable
     * @param subscribeOnMain
     * @param observeOnMain
     * @return
     */
    private static <T>  Flowable<T> getEntityObservable( Flowable<T> observable, boolean subscribeOnMain, boolean observeOnMain) {
        if (subscribeOnMain) {
            observable.subscribeOn(AndroidSchedulers.mainThread());
        } else {
            observable.subscribeOn(Schedulers.newThread());
        }

        return observeOnMain ? observable.observeOn(AndroidSchedulers.mainThread()) : observable.observeOn(Schedulers.newThread());
    }

}
